// Symbol([value]) 创建唯一值
// Symbol('A')
console.log(Symbol('A') === Symbol('A'))

// BigInt 大数据值
// JS存在最大、最小安全数字
console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER) // -9007199254740991
let num = 9007199254740993
let bignum = 9007199254740993n // 后面加n
console.log(num + 1) // 9007199254740992
console.log(bignum + 1n) // 9007199254740994n

// 奇怪的数字类型
// 1. NaN
console.log(typeof NaN) // number
console.log(NaN === NaN) // false
console.log(Object.is(NaN, NaN)) // true
// 2. 想检测一个值是否为有效数字
console.log(isNaN(10)) // false
console.log(isNaN('AA')) // true 在检测的时候如果当前这个值不是number类型，先隐式转换为number类型(Number)再判断

// 3. Infinity无穷大值
console.log(Infinity) // Infinity

let res = parseFloat('left: 200px')
if(res === 200) {
    alert(200)
} else if(res === NaN) {
    alert(NaN)
} else if(typeof res === 'number') {
    alert('number') // alert输出的结果都会转换成字符串
} else {
    alert('Infinity number')
}

/**
 * 数据类型检测
 * typeof 
 *  检测出来的结果是字符串
 *  typeof null => "object" 计算机存储采用二进制 如果开头为000 表示为object 010 浮点数 100 字符串 110 布尔
 *  检测对象细分的类型，结果都是"object"
 * instanceof
 * constructor
 * Object.prototype.toString.call([value])
 */

var a = typeof typeof typeof [12, 22]
console.log(a)


/**
 * 数据类型转换
 * 
 * 其他转换为Number
 *  1. 特定需要转换为Number的
 *      Number([val])
 *      parseInt/parseFloat([val])
 *  2. 隐式转换（浏览器内部默认先转换为number再进行计算）
 *      isNaN([val])
 *      数学运算（特殊情况： + 在出现字符串的时候不是数学运算，是字符串拼接 PS: +i/++i/i++ 这种情况为数学运算 var n = '10' ++n）
 *      在==比较的时候
 * 
 *  
 * Number机制
 *  1. 只要出现非有效数字 结果就是NaN null转换为0 undefined转换为NaN  
 *  2. 对象转数字 先valueOf 没有原始值仔toString转换为字符串 在转换为数字
 * parseInt机制
 *  先变成字符串，从字符串左侧第一个字符开始，查找有效数字字符（遇到第一个非有效字符停止查找，把找到的有效数字字符转化为数字，如果一个都没有结果就是NaN）
 * parseFloat机制
 *  比parseInt多识别一个小数点
 * 
 * 
 * 其他类型转String 
 * 其他类型转换为字符串，一般都是直接""包起来 只有{}普通对象调用toString()不是转换字符串而是检测数据类型，原因是调用了原型上的toString
 *  1. 能使用的办法
 *      toString()
 *      String()
 *  2. 隐式转换（一般都是调用其toString）
 *      加号运算的时候，如果某一边出现字符串，则是字符串拼接（特殊情况，如果+只有一方有值则为数字运算）
 *      把对象转换为数字，需要先toString()转换为字符串，再去转换为数字
 *      基于alert/confirm/prompt/document.write...这些方式输出内容，都是把内容先转换为字符串，然后再输出的
 *    
 * 把其它数据类型转换为布尔
 *  1. 基于以下方式可以把其它数据类型转换为布尔
 *      ! 转换为布尔值后取反
 *      !! 转换为布尔类型
 *      Boolean([val])
 *  2. 隐式转换
 *      在循环或者条件判断中，条件处理的结果就是布尔类型值
 * 规则：只有 ‘0、NaN、null、undefined、空字符串’ 五个值会变为布尔的FALSE，其余都是TRUE
 * 
 * 在==比较的过程中，数据转换的规则：
 *  类型一样的几个特殊点】
 *      {}=={}：false  对象比较的是堆内存的地址
 *      []==[]：false
 *      NaN==NaN：false
 *  【类型不一样的转换规则】
 *      1. null==undefined：true，但是换成===结果是false（因为类型不一致），剩下null/undefined和其它任何数据类型值都不相等
 *      2. 字符串==对象  要把对象转换为字符串
 *      3. 剩下如果==两边数据类型不一致，都是需要转换为数字再进行比较
 */



 console.log([] == false)
 console.log(![] == false)

 var b = parseInt('1.6px') + parseFloat('1.2px') + typeof parseInt(null)
 console.log(b)

 var result = 10 + false + undefined + [] + 'Tencent' + null + true + {}
 console.log(result)


console.log({} + 0) // 0 {}被认为是代码块 不参与运算
console.log(({} + 0)) // [object Object]0 ()包住被认为参与运算
console.log(0 + {}) // 0[object Object] 隐式转换




let arr = [10.18, 0, 19, 25, 23]
arr = arr.map(parseInt)
console.log(arr)


/**
 * null和undefined区别
 * 女朋友是null
 * 男朋友是undefined
 * null 当前没有，后期可能会有，一般都会有，情理之中的没有 人为设定的空
 * undefined 意料之外的 非人为设定的空
 */
























